<template>
  <div class="workflow-execution-record-detail" v-loading="loading">
    <div class="workflow-section">
      <workflow-viewer
          :dsl="dslSourceCode"
          :trigger-type="recordDetail.record?.triggerType"
          :node-infos="nodeInfos"
          :tasks="recordDetail.taskRecords"
          @click-process-log="openProcessLog"
          @click-task-node="openTaskLog"
          @click-webhook-node="openWebhookLog"
      />
    </div>
    <el-drawer
        title="查看任务执行日志"
        :size="850"
        v-model="taskLogForm.drawerVisible"
        direction="rtl"
        destroy-on-close
    >
      <task-log
          v-if="taskLogForm.drawerVisible"
          :id="taskLogForm.id"
          :tab-type="taskLogForm.tabType"
          :record-detail="recordDetail"/>
    </el-drawer>
    <el-drawer
        title="查看流程日志"
        :size="850"
        v-model="processLogDrawer"
        direction="rtl"
        destroy-on-close
    >
      <process-log :record="recordDetail.record"/>
    </el-drawer>
    <el-drawer
        title="查看Webhook日志"
        :size="850"
        v-model="webhookLogForm.drawerVisible"
        direction="rtl"
        destroy-on-close
    >
      <webhook-log
          :node-name="webhookLogForm.nodeName"
          :trigger-id="webhookLogForm.triggerId"
          :trigger-type="webhookLogForm.triggerType"
          :tab-type="webhookLogForm.tabType"
          :record-detail="recordDetail"
      />
    </el-drawer>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, onBeforeUnmount, onMounted, provide, ref, toRaw } from 'vue';
import { TaskStatusEnum, WorkflowExecutionRecordStatusEnum } from './handlers/enumeration';
import TaskLog from './task-log.vue';
import ProcessLog from './process-log.vue';
import WebhookLog from './webhook-log.vue';
import WorkflowViewer from './components/workflow/workflow-viewer/index.vue';
import sleep from './handlers/utils/sleep';
import { onBeforeRouteUpdate } from 'vue-router';
import { HttpError, TimeoutError } from './handlers/utils/error';
import { NodeToolbarTabTypeEnum } from './handlers/enumeration';
import { getRecordData } from './handlers/work-execution-data-handler';
import { RecordParams, IOpenTaskLogForm, IOpenWebhookLogForm, IWorkflowExecutionRecordVo, INodeDefVo } from './handlers/type';


export default defineComponent({
  components: { TaskLog, ProcessLog, WebhookLog, WorkflowViewer },
  props: {
    projectId: {
      type: String,
      required: true,
    },
    workflowExecutionRecordId: String,
    baseUrl:{
      type: String,
      default: '',
    },
  },
  setup(props: any) {
    provide('baseUrl', props.baseUrl);
    const loading = ref<boolean>(false);
    const recordDetail = ref<RecordParams>({
      project: undefined,
      navScrollLeft: 0,
      allRecords: [],
      record: undefined,
      recordDsl: undefined,
      taskRecords: [],
      nodeInfos: [],
    });
    const taskLogForm = ref<IOpenTaskLogForm>({
      drawerVisible: false,
      id: '',
      tabType: '',
    });
    const webhookLogForm = ref<IOpenWebhookLogForm>({
      drawerVisible: false,
      nodeName: '',
      tabType: '',
    });
    const processLogDrawer = ref<boolean>(false);
    let terminateLoad = false;

    const loadDetail = async (refreshing?: boolean) => {
      if (terminateLoad) {
        console.debug('组件已卸载，终止刷新');
        return;
      }

      try {
        if (!refreshing) {
          loading.value = !loading.value;
        }

        try {
          console.log(props);
          const record = await getRecordData({ ...toRaw(props) });
          Object.assign(recordDetail.value, record);
        } catch (err) {
          if (!refreshing) {
            throw err;
          }

          if (err instanceof TimeoutError) {
            // 忽略超时错误
            console.warn(err.message);
          } else if (err instanceof HttpError) {
            const { response } = err as HttpError;

            if (response && response.status !== 502) {
              throw err;
            }

            // 忽略错误
            console.warn(err.message);
          }
        }
        if (!refreshing) {
          loading.value = !loading.value;
        }

        const { status } = recordDetail.value
          .record as IWorkflowExecutionRecordVo;

        if (
          status === WorkflowExecutionRecordStatusEnum.RUNNING ||
            recordDetail.value.taskRecords.find(item =>
              [TaskStatusEnum.WAITING, TaskStatusEnum.RUNNING].includes(
                item.status,
              ),
            )
        ) {
          console.debug('3秒后刷新');
          await sleep(3000);
          await loadDetail(true);
        }
      } catch (err) {
        if (!refreshing) {
          loading.value = !loading.value;
        }
      }
    };

    onBeforeRouteUpdate((to, { name }) => {
      if (name !== 'workflow-execution-record-detail') {
        return;
      }
    });

    // 初始化流程执行记录详情
    onMounted(async () => {
      await loadDetail();
    });

    onBeforeUnmount(() => {
      terminateLoad = true;

      // 清空数据
      // proxy.mutateRecordDetail({});
    });
    return {
      WorkflowExecutionRecordStatusEnum,
      TaskStatusEnum,
      recordDetail,
      loading,
      dslSourceCode: computed<string | undefined>(
        () => recordDetail.value.recordDsl,
      ),
      nodeInfos: computed<INodeDefVo[]>(() => recordDetail.value.nodeInfos),
      taskLogForm,
      webhookLogForm,
      loadDetail,
      openTaskLog: (nodeId: string, tabType: NodeToolbarTabTypeEnum) => {
        taskLogForm.value.drawerVisible = true;
        taskLogForm.value.id = nodeId;
        taskLogForm.value.tabType = tabType;
      },
      processLogDrawer,
      openProcessLog: () => {
        processLogDrawer.value = true;
      },
      openWebhookLog: (nodeId: string, tabType: NodeToolbarTabTypeEnum) => {
        webhookLogForm.value.drawerVisible = true;
        webhookLogForm.value.nodeName = nodeId;
        webhookLogForm.value.tabType = tabType;
        webhookLogForm.value.triggerId = recordDetail.value.record?.triggerId;
        webhookLogForm.value.triggerType = recordDetail.value.record?.triggerType;
      },
    };
  },
});
</script>

<style scoped lang="less">
@import './assets/css/icon/input/css/jm-icon-input.css';
@primary-color: #096dd9;
@secondary-color: #0091ff;

.workflow-execution-record-detail {
  font-size: 14px;
  color: #333333;
  margin-bottom: 20px;

  .right-top-btn {
    position: fixed;
    right: 20px;
    top: 78px;

    .jm-icon-button-cancel::before {
      font-weight: bold;
    }
  }

  .basic-section {
    position: relative;
    margin-bottom: 16px;
    padding-top: 16px;
    background: #ffffff;

    .trigger-btn {
      position: absolute;
      right: 12px;
      top: 12px;
      width: 50px;
      height: 50px;
      border-radius: 4px;
      font-size: 36px;
      border: 0;
      background-color: transparent;
      color: #6b7b8d;
      cursor: pointer;

      &:active {
        background-color: #eff7ff;
      }
    }

    .info {
      padding: 0 24px;
      margin-bottom: 14px;

      .name {
        font-size: 20px;
        font-weight: bold;
        color: #082340;
        display: flex;
        align-items: center;
        margin-bottom: 8px;

        .project-group-name {
          padding: 2px 20px;
          margin-right: 10px;
          background: #f0f7ff;
          border-radius: 2px;
        }
      }

      .desc {
        margin-top: 5px;
        width: 80%;
        font-size: 14px;
        color: #6b7b8d;
      }
    }

    .instance-tabs {
      display: flex;
      color: #ffffff;
      white-space: nowrap;

      .tab + .tab {
        margin-left: 8px;
      }

      .tab {
        position: relative;
        min-width: 70px;
        //flex-basis: 70px;
        flex-shrink: 0;
        height: 60px;
        border-radius: 4px 4px 0 0;

        .left-horn,
        .right-horn {
          position: absolute;
          bottom: 0;
          width: 8px;
          height: 8px;
          overflow: hidden;

          &::before {
            content: '';
            position: absolute;
            bottom: 0;
            width: 48px;
            height: 48px;
            overflow: hidden;
            background-color: #fff;
          }
        }

        .left-horn {
          left: -8px;

          &::before {
            right: 0;
            border-bottom-right-radius: 8px;
          }
        }

        .right-horn {
          right: -8px;

          &::before {
            left: 0;
            border-bottom-left-radius: 8px;
          }
        }

        &.init {
          &,
          .left-horn,
          .right-horn {
            background-color: #979797;
          }
        }

        &.running {
          &,
          .left-horn,
          .right-horn {
            background-color: #10c2c2;
          }
        }

        &.finished {
          &,
          .left-horn,
          .right-horn {
            background-color: #3ebb03;
          }
        }

        &.terminated {
          &,
          .left-horn,
          .right-horn {
            background-color: #cf1524;
          }
        }

        &.unselected {
          cursor: pointer;
          height: 59px;
          border-bottom: 1px solid #fff;
          opacity: 0.55;

          .label {
            padding: 7px 10px 0;
            text-align: right;
            font-size: 20px;
          }
        }

        &.selected {
          cursor: default;

          .label {
            padding-left: 4px;
            line-height: 60px;
            font-size: 26px;
            text-align: center;

            &::before {
              content: '';
              position: absolute;
              left: 0;
              top: 15px;
              width: 4px;
              height: 30px;
              background: rgba(255, 255, 255, 0.8);
              border-radius: 0 100px 100px 0;
              overflow: hidden;
            }
          }
        }
      }
    }

    .instance-tab-content {
      position: relative;
      display: flex;
      padding: 15px 30px;
      color: #ffffff;

      &.init {
        background-color: #979797;
      }

      &.running {
        background-color: #10c2c2;
      }

      &.finished {
        background-color: #3ebb03;
      }

      &.terminated {
        background-color: #cf1524;
      }

      .item + .item {
        margin-left: 80px;
      }

      .item {
        font-size: 14px;

        .value {
          font-size: 16px;
          font-weight: bold;
          margin-bottom: 5px;
        }
      }

      .terminate-btn {
        position: absolute;
        top: 14px;
        right: 12px;
        width: 50px;
        height: 50px;
        border-radius: 4px;
        font-size: 36px;
        border: 0;
        background-color: transparent;
        color: #ffffff;
        cursor: pointer;

        &:active {
          background-color: #55dbdb;
        }
      }
    }
  }

  .workflow-section {
    background-color: #ffffff;
    height: calc(100vh - 384px);
  }

  ::v-deep(.el-tabs__nav-scroll) {
    line-height: 46px;
  }

  ::v-deep(.el-drawer) {
    .el-drawer__body {
      padding: 0;
      overflow: hidden;
    }
    .el-drawer__header {
      color: #082340;
      background-color: #FFFFFF;
      padding: 20px 25px;
      margin-bottom: 0;
      font-size: 16px;
      border: 1px solid #CAD6EE;

      > span::before {
        font-family: 'jm-icon-input';
        content: '\e803';
        margin-right: 10px;
        color: #6b7b8d;
        font-size: 20px;
        vertical-align: bottom;
      }
      .el-drawer__close-btn {
        width: 26px;
        height: 26px;
        background-color: #082340;
        box-shadow: 0 4px 10px 0 #8c8c8c;
        border-radius: 2px;
        color: #fff;
        display: inline-flex;
        justify-content: center;
        align-items: center;
      }
    }
    &.ltr, &.rtl, &.ttb, &.btt {
      animation: none;
    }
  }
}
</style>
